Skip to content

Latest commit

 

History

History
191 lines (161 loc) · 6.08 KB

File metadata and controls

191 lines (161 loc) · 6.08 KB

原文链接

动机:

前言:为什么需要webpack? webpack产生的动机是?

在这个时代,越来越多的网站已经开始进化成web应用了:

  • 越来越多的javascript运用在页面
  • 在现代的浏览器上实现更多的功能
  • 更少的整页重加载

结果必然是会导致客户端上存在着大量的代码需要去维护、开发。

大量的代码库需要被组织起来,所以模块系统提供了一个选择,它将可以把你的代码模块划分为各个小模块。

模块系统风格

有很多不同的标准去定义依赖关系和导出值:
  • script 标签 风格(非模块系统)
  • CommonJS
  • AMD
  • ES6 模块
  • 还有更多...

script 标签风格

如果你没有使用模块系统,你可以用这样的传统方式去处理一个模块化的代码库。 ``` <script src="module1.js"></script> <script src="module2.js"></script> <script src="libraryA.js"></script> <script src="module3.js"></script> ```

模块导出到全局对象的接口, 即window对象。模块可以访问全局对象的依赖借口。

常见问题

  • 得注意全局对象是否冲突
  • 得注意文件加载顺序
  • 开发人员必须解决模块/库之间的依赖关系
  • 在大型项目下,代码/文件将会越来越庞大并且后期将难以维护

CommonJS: 同步加载

这种风格使用了同步的方法来require加载依赖并返回一个输出接口。模块可以通过添加属性来指定export对象或者设置module.export的值 ``` require("module"); require("../file.js"); exports.doStuff = function() {}; module.exports = someValue; ``` node.js 就是使用这种服务器端的js.

优势:

  • 服务器端模块可以重用
  • 已经有很多这种风格的模块(npm)
  • 非常简单、易用

缺陷:

  • 阻塞调用不太适合于网络环境,因为网络请求是异步的
  • 不能并行加载多个模块

实践

AMD: 异步加载

异步加载解决了浏览器并行下载的问题,并且也有方法可以去定义模块还有导出值,如下面例子: ``` require(["module", "../file"], function(module, file) { /* ... */ }); define("mymodule", ["dep1", "dep2"], function(d1, d2) { return someExportedValue; }); ```

优势

  • 适用于网络中的异步请求方式
  • 多个模块并行加载

缺陷

  • 编码开销大(额外代码多)
  • 更难读写

实践

了解更多commonjs和amd 模式,在这里推荐阮一峰老师的好文: 传送门

ES6 模块:

为了支持模块系统,ecmaScript6 增加了一些新的语法来支持它 ``` import "jquery"; export function doStuff() {} module "localModule" {} ```

优势

  • 静态分析简单
  • 未来ES的标准

缺陷

  • 本地浏览器支持需要时间
  • 暂时还很少有运用es6风格的模块

数据传输

由于客户端需要执行模块,因此模块必须从服务器传输到浏览器。

传输模块有2种极端方式:

  • 每个模块为一个请求
  • 所有模块打包成一个请求

两种都是被广泛使用的,但是两者都不是最佳方式:

  • 每个模块为一个请求
    • 优势: 只有需要的模块才会被传输
    • 缺陷: 太多请求开销导致页面请求阻塞延迟,应用启动慢
  • 所有模块来自一个请求
    • 优势: 少量请求开销,少量阻塞延迟,页面加载快
    • 缺陷: 不需要的模块也会被传输

分块传输

看过上面两种方式后,肯定大家会觉得上面两种方式都不是很靠谱,假如有另外一个更灵活的传输方式会更好,即在大多数情况下,两种方式都可以互相妥协、互补。

比如:编译所有模块时,可以把模块分成多个更小的块

这样的话,我们可以得到多个较小的文件请求,不必要的模块只会在需要加载的页面下才会被请求,初始请求不会加载全部的代码库。

备注:这个想法是来自谷歌的GWT

了解更多 代码分割

为什么只有javascript?

为什么模块系统只帮助开发者去模块化js而已?实际项目开发上还有很多静态资源也需要一起被模块化,如:
  • css样式
  • 图像
  • web字体
  • html模版
  • 更多...

还有:

  • coffeescript 转换成 javascript
  • less/sass 样式 转换成 css 样式
  • jade templates → javascript which generates html
  • i18n files → something
  • 更多...

这些应该也要有简单的方式去加载,如:

require("./style.css");
require("./style.less");
require("./template.jade");
require("./image.png");

了解更多 加载器使用方法加载器

以上的种种原因就是产生webpack的动机。